package joc;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

import joc.transformer.Transformer;

import org.apache.log4j.Logger;

public class Invoker {
	private static Logger logger = Logger.getLogger(Invoker.class);
	
	protected static Logger getLogger() {
		return logger;
	}
	
	protected static void setLogger(Logger logger) {
		Invoker.logger = logger;
	}

	public static void callContract(Class<? extends Annotation> annotationClass, Method method, Object[] args) throws Exception {
		logger.debug("invoking contract " + annotationClass.getName() + " with method " + method.getName() + " and " + args.length + " args");
		try {
			if (!((Boolean) method.invoke(Transformer.getContractMap().get(annotationClass), args)).booleanValue()) {
				throw new AssertionError();
			}
		} catch (IllegalArgumentException e) {
			Class<?>[] argTypes = new Class<?>[args.length];
			for (int i = 0; i < args.length; i++) {
				argTypes[i] = args[i].getClass();
			}
			logger.error("invalid call to contract, expected parameters: " + Arrays.toString(method.getParameterTypes()) + ", actual parameters: " + Arrays.toString(argTypes), e);
		}
	}
	
	public static class ObjectConverter {
		public static Boolean toObject(boolean value) {
			return Boolean.valueOf(value);
		}
		public static Byte toObject(byte value) {
			return Byte.valueOf(value);
		}
		public static Character toObject(char value) {
			return Character.valueOf(value);
		}
		public static Double toObject(double value) {
			return Double.valueOf(value);
		}
		public static Float toObject(float value) {
			return Float.valueOf(value);
		}
		public static Integer toObject(int value) {
			return Integer.valueOf(value);
		}
		public static Long toObject(long value) {
			return Long.valueOf(value);
		}
		public static Object toObject(Object value) {
			return value;
		}
		public static Short toObject(short value) {
			return Short.valueOf(value);
		}
	}

}
